import React, { useState, useMemo, useReducer, useEffect } from 'react';
import { cline, sn_name, obj_str, obj_empty, obj_bool, for_obj, Btn, Title, Ret, useHigh, WaitUmd, MainView, PanelTitle, useCmd, uDb, loc } from 'sui';
import { get_item, g_access } from './base';

const reducer = (status, action) => {
    const type = action.type;
    if (type === "clear") {
        return {};
    }
    else if (type === "set") {
        const ret = {
            ...status,
        };

        for_obj(action, (k, v) => {
            if (k === "type") {
                return;
            }

            ret[k] = v;
        });

        return ret;
    }

    return status;
}

const Auth = ({ cur, hreturn }) => {
    const [cfg, setCfg] = useState(null);
    const [high] = useHigh(140, 100);
    const [status, dispatch] = useReducer(reducer, {});
    const umd = useCmd();

    useEffect(() => {
        uDb(null, "setting/get", {line: cline()}, r => setCfg(r.mod), e => setCfg(null));
    }, []);

    useEffect(() => {
        uDb(null, "auth/get",
            {
                line: cline(),
                k: obj_str(cur, "sn"),
            },
            r => {
                const tmp = {};

                let mod = obj_str(r, "val");
                if (mod) {
                    mod = mod.split(",");
                    mod.forEach(d => tmp[d] = true);
                }

                let access = obj_str(r, "rval");
                if (access) {
                    access = access.split(",");
                    access.forEach(d => tmp[d] = true);
                }

                if (obj_empty(tmp)) {
                    return;
                }

                dispatch({
                    ...tmp,
                    type: "set",
                });
            },
            e => dispatch({type: "clear"}), cur.uid);
    }, [cur]);

    const getCtl = useMemo(() => {
        if (obj_empty(cfg)) {
            return null;
        }

        const ret = get_item(cfg, k => obj_bool(status, k), (k, v) => {
            const d = {};
            d[k] = v;

            dispatch({
                ...d,
                type: "set",
            });
        });

        return ret;
    }, [status, cfg]);

    const hdone = () => {
        umd.startWait();

        const access = g_access();
        const mod = new Set();

        access.forEach(d => mod.add(obj_str(d, "k")));

        const val = [];
        const rval = [];

        for_obj(status, (k, v) => {
            if (!v) {
                return;
            }

            if (mod.has(k)) {
                val.push(k);
            }
            else {
                rval.push(k);
            }
        });

        uDb(null, "auth/mditem",
            {
                line: cline(),
                sn: obj_str(cur, "sn"),
                v: {
                    sn: obj_str(cur, "sn"),
                    val: val.join(","),
                    rval: rval.join(","),
                }
            },
            r => {
                umd.endWait();
                hreturn();
            },
            e => umd.setErr(loc("l_103")), true);
    };

    const Right = () => (
        <div className="inline-flex">
            <Btn hcmd={hdone} color="green" className="mr-4">{loc("l_234")}</Btn>
            <Ret hcmd={hreturn}/>
        </div>
    );

    return (
        <MainView>
            <PanelTitle left={<Title mod={sn_name(cur)} sub={loc("l_118")}/>} right={<Right/>} cl="gray"/>
            <div className="overflow-y-auto" style={{ height: high + "px" }}>
                {getCtl}
            </div>
            <WaitUmd umd={umd}/>
        </MainView>
    );
};

export {Auth};
